package com.woniuxy.lab.woniu_lab.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.woniuxy.lab.woniu_lab.commons.Result;
import com.woniuxy.lab.woniu_lab.config.AlipayConfig;
import com.woniuxy.lab.woniu_lab.exception.WebException;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.woniuxy.lab.woniu_lab.service.ChargeService;
import com.woniuxy.lab.woniu_lab.service.dto.ChargeDto;
import com.woniuxy.lab.woniu_lab.util.JwtUtil;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 充值记录表 前端控制器
 * </p>
 *
 * @author Silas
 * @since 2023-03-15
 */
@RestController
@RequestMapping("/charge")
@Slf4j
@Api(tags = "[B]充值记录相关接口")
@Validated
public class ChargeController {
    @Value("${max_top_up_money}")
    public int MAXMONEY;
    @Resource
    private ChargeService chargeService;




    @ApiOperation("17 获取我的充值记录")
    @GetMapping("/myCharge")
    public Result<IPage<ChargeDto>> myCharge(@ApiParam(value = "第几页") @Min(value = 1 ,message = "当前页最小为1") Integer page,
                                             @ApiParam(value = "每页条数") @Min(value = 3, message = "最小展示数量为3")
                                             @Max(value = 50, message = "最大展示数量为50") Integer size) {
        Integer userId = JwtUtil.getUserIdFromReq();
        log.info("用户{}查询充值记录{}{}", userId, page, size);
        IPage<ChargeDto> myCharge = chargeService.findMy(userId, page, size);
        return Result.success(200, "查询充值记录成功", myCharge);
    }

    @ApiOperation("25 创建充值订单")
    @PostMapping("/createOrder")
    public Result<String> createOrder(@ApiParam(value = "充值金额") @RequestParam @NotNull(message = "充值金额不能为空")
                                          @Min(value = 10,message = "充值金额最低为10元")
                                          @Digits(integer = 8,fraction = 0,message = "充值金额只能是整数") BigDecimal money)  {
        log.info("创建充值订单{}",money);
        if (money.compareTo(BigDecimal.valueOf(MAXMONEY)) > 0) {
            throw new WebException(400,"感谢您的支持,暂时不支持该"+MAXMONEY+"元以上的充值");
        }
        String result = chargeService.createOrder(money);
        return Result.success(200,"创建成功",result);
    }

    @ApiIgnore// 该接口不会被显示在文档中
    @PostMapping("/alipayCallback")
    public String doPayCallback(HttpServletRequest request) throws AlipayApiException {

        log.info("支付回调");
        //支付宝验签
        Map<String, String> parameterMap = convertParams(request.getParameterMap());
        log.info("回调所有参数：{}",parameterMap);
        boolean verifySuccess = AlipaySignature.verifyV1(parameterMap, AlipayConfig.alipayPublicKey, AlipayConfig.charset, AlipayConfig.signType);
        String outTradeNo = parameterMap.get("out_trade_no");
        String tradeStatus = parameterMap.get("trade_status");
        if(verifySuccess){
            //修改订单状态
            if(tradeStatus.equals("TRADE_SUCCESS")||tradeStatus.equals("TRADE_FINISHED")) {
                chargeService.paySuccess(outTradeNo);
            }else{
                log.warn("订单支付回调结果不正常：{},{}",outTradeNo,tradeStatus);
            }
        }else{
            log.warn("支付宝回调验签失败：{}",outTradeNo);
        }

        return "success";
    }

    /**
     * 参数解析
     * @param parameterMap 返回的参数map
     * @return 解析后的map
     */
    private Map<String, String> convertParams(Map<String, String[]> parameterMap) {
        Map<String,String> retMap = new HashMap<>();
        Set<Map.Entry<String, String[]>> entrySet = parameterMap.entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }
        return retMap;
    }

    @ApiOperation("27 继续支付充值订单")
    @PostMapping("continuePay")
    public Result<Object> continuePay(@ApiParam(value = "充值订单号") @RequestParam
                                          @NotBlank(message = "订单号不能为空") String no){
        log.info("继续支付{}",no);
        String result ="";

        result = chargeService.continuePay(no);

        return Result.success(200,"继续支付",result);
    }

    @ApiOperation("28 取消充值订单")
    @PostMapping("cancelOder")
    public Result<Object> cancelPay( @ApiParam(value = "充值订单号") @NotBlank(message = "订单号不能为空") @RequestParam String no){
        log.info("取消订单{}",no);
        chargeService.cancelPay(no);
        return Result.success(200,"取消订单成功",null);
    }
}

